import cherrypy
import os, sys, re, pdb, logging, tempfile
from logst.helpers import *

sys.path.append('/usr/share/checksysreport')

logger = logging.getLogger('logpox')

if os.path.isdir("%s/.checksysreport" % os.environ["HOME"]):
   try:
      import sysreportChecker
      import globals
   except:
      logger.warn("checksysreport is installed but not configured.")

# In order to detect suitable base channel, there are 3 things to detect:
# 
# osRelease:  2.1,3, or 4
# flavour:    es as ws desktop
# arch        ia64 i386 x86_64 ppc s390 s390x
#
# osRelease has to be known before creating an instance as there are
# subclasses according to the osRelease used.
def detect_release(path):
    """
    Try to detect the RHEL release from the sysreport located in path
    Return '2.1' '3' '4' 'unsupported' or '0' if unknown
    """
    redhatReleasePath=path+'/etc/redhat-release'
    if os.path.isfile(redhatReleasePath):
        RELEASE=open(redhatReleasePath,'r')
        out='0'
        for line in RELEASE:
            rhelreg3=re.compile(r"Red Hat Enterprise Linux .* release (\d)")
            rhelmatch3=rhelreg3.match(line)
            rhelreg2AS=re.compile("Red Hat Linux Advanced Server release 2.1.*")
            rhelmatch2AS=rhelreg2AS.match(line)
            rhelreg2ES=re.compile(r"Red Hat Enterprise Linux ES release 2.1.*")
            rhelmatch2ES=rhelreg2ES.match(line)
            rhelregDesktop=re.compile(r"Red Hat Desktop release (\d)")
            rhelmatchDesktop=rhelregDesktop.match(line)
            
            if rhelmatch2AS or rhelmatch2ES:
                RELEASE.close()
                return '2.1'
            if rhelmatch3:
                RELEASE.close()
                return str(rhelmatch3.group(1))
            if rhelmatchDesktop:
                RELEASE.close()
                return str(rhelmatchDesktop.group(1))

        RELEASE.close
    else:
        globals.die("no such file:"+redhatReleasePath)

def sosReportCompat(dir):
    """
    Prepare the archive if it has been generated by sosreport so it looks like
    a sysreport archive
    """
    if not os.path.isdir(dir+"/sos_logs"):
        return

    targets={"/installed-rpms":"/sos_commands/rpm.rpm_-qa_--qf_---NAME----VERS",\
             "/uname":"/sos_commands/kernel.uname_-a",\
             "/lsmod":"/sos_commands/kernel.lsmod",\
             "/rpm-Va":"/sos_commands/rpm.rpm_-Va"}
    
    for dest in targets:
        full_src=dir+"/"+targets[dest]
        full_dest=dir+"/"+dest
        if not os.path.isfile(full_dest) and os.path.isfile(full_src): 
            shutil.copyfile(full_src,full_dest)

class host:

   def checksysreport(self, hostname = "fs03-lx"):

      logger = logging.getLogger('logpox')
      cluster = cherrypy.root.cluster_master.instance()
      host = cluster.hosts[hostname]
      checker = self.get_checker(hostname)

      yield cherrypy.root.header()

      yield """

<div style="text-align: right; float: right">

  <h2>checksysreport output for <b>%s</b></h2>
  <br>
  <table class="grid" style="width: 300px">
    <tr class="even"><td style="font-weight: bold">Architecture</td>	<td style="text-align: right">%s</td></tr>
    <tr class="odd"> <td style="font-weight: bold">Release</td>		<td style="text-align: right">%s</td></tr>
    <tr class="even"><td style="font-weight: bold">Flavour</td>		<td style="text-align: right">%s</td></tr>
    <tr class="odd"> <td style="font-weight: bold">Base</td>		<td style="text-align: right">%s</td></tr>
    <tr class="even"><td style="font-weight: bold">Kernel</td>		<td style="text-align: right">%s</td></tr>
  </table>
</div>
""" % ( hostname, checker.osArch, checker.osRelease, checker.osFlavour, checker.baseChannel, host.sos.kernel_version())

      #
      # Packages to update
      #

      yield "<h3>Package updates available:</h3>"

      pkg_name = None

      obsoletes = checker.get_obsolete_rpms()

      while True:

         try:    o = obsoletes.pop(0)
         except: break

         new_pkg_name = "%s-%s-%s-%s" % (
		o['current']['package_name'],
		o['current']['package_version'],
		o['current']['package_release'],
		o['current']['package_arch_label']
	 )

         if new_pkg_name == pkg_name:
            continue

         pkg_name = new_pkg_name

#{'current': {'package_arch_label': 'x86_64', 'channel_label': 'rhel-x86_64-ws-4',
# 'package_name': 'libwnck', 'package_version': '2.8.1', 'package_release': '1.rhel4.1', 
# 'package_id': 328441}, 'latest': {'package_arch_label': 'x86_64', 
# 'channel_label': 'rhel-x86_64-ws-4', 'package_name': 'libwnck', 'package_epoch': ' ',
# 'package_version': '2.8.1', 'package_release': '7.el4', 'package_id': 425608, 
# 'package_last_modified': None}}

         if(o['current']['package_version'] != (str(o['latest']['package_version'])+'0')):

             yield """
<div style="padding-left: 20px; padding-bottom: 5px;">
	<img style="padding-top: 5px" src="/static/images/wrh-bug.gif">
	%s <a href="javascript:load_errata_details('%s','%s');">[more]</a>
	<div id="pkg_upd_%s" class="hidden_div"></div>
</div>

""" % 	     (	pkg_name,
		hostname,
		pkg_name,
		pkg_name
	     )


      yield '<PRE>'

      logger.debug("more parsing")

      yield "#######     Kernel info      ########\n"
      running=checker.getRunningKernel()
      unsupportedModules=0
      unsupportFLag=0
      taint=checker.kernel_is_tainted()
      if taint:
         print "%s\n" % taint

      yield "######   Unsupported rpms:   ########\n"
      for p in checker.get_list_3rdParty_installed_rpms():
         yield "%s\n" % p

      yield '</PRE>'

      logger.debug("finished")

      cherrypy.session['sos_checkers'][hostname] = checker

      yield cherrypy.root.footer()

   def rpc_errata_details(self, hostname, pkg_name):

      logger = logging.getLogger('logpox')
      checker = self.get_checker(hostname)

      current = self.pkg_from_string(checker, pkg_name)

      current['channel_label'] = checker.baseChannel
      current['package_id'] = checker.guess_package_id(current)

      for new in checker.supportedLatestPackages:

         if not (current["package_name"] == new["package_name"] and current["package_arch_label"] == new["package_arch_label"]):
#            if new["package_name"].startswith("cups"):
#               pdb.set_trace()
            continue

         for rhea in checker.list_advisories(current):

            yield """<div style="padding-top: 20px"><b>%s</b> is available on channel <b>%s</b></div>""" % (self.string_from_pkg(new), current["channel_label"])

            yield """<div style="padding-top: 10px; padding-left: 15px"><a href="http://rhn.redhat.com/errata/%s.html">%s</a>""" % (rhea, rhea)

            yield """<div style="padding-top: 10px; padding-left: 15px">"""
            bugs=checker.get_bugs_for_errata(rhea)
            for bz in bugs:
               yield """<a href="https://bugzilla.redhat.com/show_bug.cgi?id=%d">BZ#%d</a> %s<br>""" % (bz, bz, bugs[bz])

            yield """</div></div>"""

      else:
         logger.error("cannot find %s" % pkg_name)

#        for c in self.childsChannels:

   def rpc_sos_3rd_party(self):

      pass

   def pkg_from_string(self, checker, line):

      p=re.compile(r"^([0-9a-zA-Z\-_]+)-([0-9]+.*)-(.+)-(.+)$")

      m = p.match(line)

      if not m:
         return False

      tmpDic={}
      tmpDic['package_name']=m.group(1)
      tmpDic['package_version']=m.group(2)
      tmpDic['package_release']=m.group(3)
      tmpDic['package_arch_label']=m.group(4)

      return tmpDic

   def string_from_pkg(self, o):

      return "%s-%s-%s-%s" % (
		o['package_name'],
		o['package_version'],
		o['package_release'],
		o['package_arch_label']
	 )

   def get_checker(self, hostname):

      checkers = cherrypy.session.get('sos_checkers', False)
      if not checkers:
         checkers = {}
         cherrypy.session['sos_checkers'] = checkers

      elif checkers.has_key(hostname):
         return checkers[hostname]

      host = cherrypy.root.cluster_master.hosts[hostname]

      if not host.has_sos():
         return False

      path_root = host.sos.path_root

      if host.sos.tar:
         # it's a tar file, we need to extract the files we need for checksysreport

         tmpdir = tempfile.mkdtemp(prefix = "chksosrep_", dir = cherrypy.root.CONFIG["tmpdir"])

         for chk_file in [ "/etc/redhat-release", "installed-rpms", "uname", "lsmod" ]:
            host.sos.extract(chk_file, tmpdir)

         path_root = tmpdir + "/" + path_root

      class options:
        listPackages = None
        listChannels = None
        listChannels = None
        pidToDiff = None
        noChangelog = None
        listAllPackages = None
        arch = None
        fullChangelog = None

      options.sysreportDir = path_root

      release=detect_release(options.sysreportDir)

      if release=='2.1':
            checker=sysreportChecker.sysreportChecker_2(sysreportPath=options.sysreportDir,options=options)
      if release=='3':
            checker=sysreportChecker.sysreportChecker_3(sysreportPath=options.sysreportDir,options=options)
      if release=='4':
            checker=sysreportChecker.sysreportChecker_4(sysreportPath=options.sysreportDir,options=options)
      if release=='5':
            checker=sysreportChecker.sysreportChecker_5(sysreportPath=options.sysreportDir,options=options)

      checker.get_obsolete_rpms_cached = Memoize(checker.get_obsolete_rpms)

      cherrypy.session['sos_checkers'][hostname] = checker

      return checker

#   index.exposed = True
   checksysreport.exposed = True
   rpc_errata_details.exposed = True
